const { resolve } = require("../../课程资料/01-01-study -materials/01-01-codes/01-01-03-01-my-promise/myPromise");

const PENDING= 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise{
    constructor(excutor){
        excutor(this.resolve, this.reject);

    }

    // promise 状态
    status = PENDING;
    // 成功之后的值
    value = undefined;
    // 失败之后的值
    reason = undefined;
    // 成功回调
    successCallback = [];
    // 失败回调
    failedCallBack = [];

    static resolve(value){
        if(value instanceof MyPromise){
            return value;
        }
        return new MyPromise(resolve=>resolve(value));
    }

    static reject(reason){
        if(reason instanceof MyPromise){
            return reason;
        }
        return new MyPromise((reason, reject)={
            reject(reason);
        });
    }

    // 入参为promise列表，返回一个promise 对象
    // 列表中一个reject则返回reject， 所有成功后按顺序返回resolve结果
    static all(promises){
        return new MyPromise((resolve, reject)=>{
            // 缓存 promise resolve结果
            let result = [];
            // 所有promise resolve标记
            let index = 0;
            function addData(i, value){
                reuslt[i] = value;
                index++;
                if(index === promises.length){
                    resolve(result);
                }
            }
            for(let i = 0; i< promises.length; i++){
                if(promises[i] instanceof MyPromise){
                    promises[i].then(value=>{
                        addData(i, value);
                    }, reason=>{
                        reject(reason);
                    })
                } else {
                    addData(i, promises[i]);
                }            
            }
        })
    }


    // 将status由Pending修改为FULFILLED
    resolve = value=>{
        if(thi.status !== PENDING){
            return;
        }
        this.status = FULFILLED;
        this.value = value;
        // 执行成功回调
        while(this.successCallback.length){
            this.successCallback.shift()();
        }
    }

    // 将status由Pending改为Rejected
    reject = reason=>{
        if(this.status !== PENDING){
            return;
        }
        this.status = REJECTED;
        this.reason = reason;
        // 执行失败回调
        while(this.failedCallBack.length){
            this.failedCallBack.shift()();
        }
    }

    // 链式回调then
    then(successCallback=value=>value, failedCallBack=reason=>{throw reason}){
        let promise2 = new MyPromise((resolve, reject)=>{
            if(this.status === FULFILLED){
                // 成功时异步执行成功回调
                setTimeout(() => {
                    let x = successCallback(this.value);
                    resolvePromise(promise2, x, resolve, reject);
                }, 0);
            } else if(this.status === REJECTED){
                // 失败时异步执行失败回调
                setTimeout(() => {
                    let x = failedCallBack(this.reason);
                    this.resolvePromise(promise2, x, resolve, reject);
                }, 0);
            } else {
                // 等待时将回调缓存在数组中
                this.successCallback.push((value)=>{
                    setTimeout(() => {
                        let x = successCallback(value);
                        this.resolvePromise(promise2, x, resolve, reject);
                    }, 0);
                })
                this.failedCallBack.push((reason)=>{
                    setTimeout(() => {
                        let x = failedCallBack(reason);
                        this.resolvePromise(promise2, x, resolve, reject);
                    }, 0);
                })
            }
        })
        return promise2;
    }

    catch(failedCallBack){
        return this.then(undefined, failedCallBack);
    }
    

    finally(callback){
        return this.then((value)=>{
            MyPromise.resolve(callback()).then(()=>value);
        }, reason => {
            MyPromise.resolve(callback()).then(()=>{throw reason});
        });
    }

    resolvePromise(promise2, x, resolve, reject){
        if(promise2 === x){
            reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
        if(x instanceof MyPromise){
            x.then(resolve, reject);
        } else {
            resolve(x);
        }
    }


}